
package com.jojoteamwork.photo.ui;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.jojoteamwork.photo.R;
import com.jojoteamwork.photo.download.DownloadTask;
import com.jojoteamwork.photo.provider.Magazine;
import com.jojoteamwork.photo.util.HttpUtils;
import com.jojoteamwork.photo.util.ImageCache;
import com.jojoteamwork.photo.util.ImageCache.ImageCacheParams;
import com.jojoteamwork.photo.util.ImageFetcher;
import com.jojoteamwork.photo.util.ImageWorker;
import com.jojoteamwork.photo.util.ImageZipLoader;
import com.jojoteamwork.photo.util.Utils;
import com.jojoteamwork.photo.util.ZipDataReader;
import com.uucun.adsdk.UUAppConnect;
import com.uucun.adsdk.UpdatePointListener;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import java.lang.ref.WeakReference;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class MagazineFragment extends Fragment implements OnItemClickListener {
    // private DBHelper dbHelper;

    // private UUAppConnect appConnect;

    private static final String IMAGE_CACHE_DIR = "thumbs";

    private String password;

    public MagazineFragment() {
    }

    private GridView gridView;

    private ImageWorker mImageNetLoader;

    private ImageWorker mImageZipLoader;

    private int mImageThumbSize;

    private TextView tvNowpoint;

    private int mPoint;

    private static final int MSG_GET_POINT_RETURN = 0;

    // private static final int MSG_SAVE_PHOTO = 1;

    protected static final int MSG_NOT_ENOUGH = 2;

    protected static final int MSG_GET_POINT = 3;

    protected static final int MSG_UPDATE_POINT_ERROR = 4;

    protected static final int MSG_SPEND_POINT = 5;

    protected static final int MSG_UPDATE_GRIDVIEW = 6;

    public ProgressBar mProgressBar;

    private ExecuteHandler mHandler;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Environment.getExternalStorageState().equals(Environment.)
        setHasOptionsMenu(true);
        SharedPreferences preferences = getActivity().getSharedPreferences("setting",
                Context.MODE_PRIVATE);
        password = preferences.getString("psw", null);

        ImageCacheParams cacheParams = new ImageCacheParams(IMAGE_CACHE_DIR);

        // 设置机子内存的1/3大小作为缓存
        cacheParams.memCacheSize = 1024 * 1024 * Utils.getMemoryClass(getActivity()) / 3;
        cacheParams.diskCacheEnabled = false;

        mImageThumbSize = getResources().getDimensionPixelSize(R.dimen.image_thumbnail_size);
        mImageNetLoader = new ImageFetcher(getActivity(), mImageThumbSize);
        mImageNetLoader.setLoadingImage(R.drawable.empty_photo);
        mImageNetLoader.setImageCache(ImageCache.findOrCreateCache(getActivity(), cacheParams));

        mImageZipLoader = new ImageZipLoader(getActivity());
        mImageZipLoader.setLoadingImage(R.drawable.empty_photo);
        mImageZipLoader.setImageCache(ImageCache.findOrCreateCache(getActivity(), cacheParams));

        mHandler = new ExecuteHandler(this);
    }

    @Override
    public void onResume() {
        getPoint();
        super.onResume();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.magazine_main, null);
        gridView = (GridView) view.findViewById(R.id.gridMagazine);
        mProgressBar = (ProgressBar) view.findViewById(R.id.progressBar);
        tvNowpoint = (TextView) view.findViewById(R.id.nowpoint);
        view.findViewById(R.id.ShowOffers).setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                UUAppConnect.getInstance(getActivity()).showOffers();
            }
        });
        mHandler.sendEmptyMessage(MSG_UPDATE_GRIDVIEW);
        gridView.setOnItemClickListener(this);
        gridView.setOnItemLongClickListener(new OnItemLongClickListener() {

            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {

                final Magazine magazine = ((MagazineAdapter.ViewHolder) view.getTag()).magazine;
                if (magazine.exists)
                    Utils.showDefaultAlertDialog(getActivity(), getString(R.string.prompt),
                            getString(R.string.delete_message),
                            new DialogInterface.OnClickListener() {

                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    Utils.deleteFile(Utils.MAGAZINE_DIR + "/" + magazine.filename);
                                    mHandler.sendEmptyMessage(MSG_UPDATE_GRIDVIEW);
                                }
                            });
                return true;
            }
        });
        return view;
    }

    @Override
    public void onDestroy() {
        UUAppConnect.getInstance(getActivity()).exitSdk();
        super.onDestroy();
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        if (password == null || TextUtils.isEmpty(password)) {
            menu.add(0, 1, 1, R.string.set_password);
        } else {
            menu.add(0, 1, 1, R.string.update_password);
        }
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        Intent intent;
        switch (item.getItemId()) {
            case 1:
                if (password == null || TextUtils.isEmpty(password)) {
                    intent = new Intent(getActivity(), SetPasswordActivity.class);
                } else {
                    intent = new Intent(getActivity(), PasswordActivity.class);
                    intent.putExtra("update", true);
                }
                startActivity(intent);
                return true;
            case 2:
                // appConnect.showFeedback();
                return true;
        }
        return false;

    }

    private class UpdateTask extends AsyncTask<String, Void, ArrayList<Magazine>> {

        GridView mGridView;

        UpdateTask(GridView gridView) {
            mGridView = gridView;
        }

        @Override
        protected void onPreExecute() {
            mProgressBar.setVisibility(View.VISIBLE);
            super.onPreExecute();
        }

        @Override
        protected ArrayList<Magazine> doInBackground(String... params) {

            String url = params[0];
            String[] filenames = Utils.findFilesBySuffix(Utils.MAGAZINE_DIR, "kmd");
            ArrayList<Magazine> magazines = new ArrayList<Magazine>();
            if (filenames != null) {
                for (String filename : filenames) {
                    String description = ZipDataReader.getText(Utils.MAGAZINE_DIR + "/" + filename,
                            "description");

                    Magazine magazine = buildMagazineFromDescription(description);
                    if (magazine != null) {
                        magazines.add(magazine);
                    }
                }
            }
            if (HttpUtils.checkConnection(getActivity())) {

                String result = HttpUtils.loadString(url);
                if (!TextUtils.isEmpty(result)) {
                    ArrayList<Magazine> onlineMagazines = buildMagazinesFromOnlineJson(result);
                    if (onlineMagazines != null && onlineMagazines.size() > 0) {
                        for (Magazine magazine : onlineMagazines) {
                            if (filenames != null) {
                                for (String filename : filenames) {
                                    if (magazine.filename.equals(filename)) {
                                        magazine.exists = true;
                                        break;
                                    }
                                }
                            }
                            if (!magazine.exists) {
                                magazines.add(magazine);
                            }

                        }
                    }
                }
            }
            Collections.sort(magazines, new Comparator<Magazine>() {
                @Override
                public int compare(Magazine lhs, Magazine rhs) {
                    if (lhs.id > rhs.id) {
                        return 1;
                    } else if (lhs.id < rhs.id) {
                        return -1;
                    }

                    return 0;
                }
            });
            return magazines;

        }

        @Override
        protected void onPostExecute(ArrayList<Magazine> magazines) {
            if (magazines != null && magazines.size() > 0) {
                MagazineAdapter adapter = (MagazineAdapter) mGridView.getAdapter();
                if (adapter == null) {
                    adapter = new MagazineAdapter(magazines);
                    mGridView.setAdapter(adapter);
                } else {
                    adapter.changeMagazines(magazines);
                }

            }
            mProgressBar.setVisibility(View.GONE);
            UpgradeTask upgradeTask = new UpgradeTask();
            upgradeTask.execute();
        }

    }

    private Magazine buildMagazineFromDescription(String description) {
        if (description != null && !TextUtils.isEmpty(description)) {
            Gson gson = new Gson();

            Type type = new TypeToken<Magazine>() {
            }.getType();
            Magazine magazine = gson.fromJson(description, type);
            magazine.exists = true;
            return magazine;
        }
        return null;
    }

    private ArrayList<Magazine> buildMagazinesFromOnlineJson(String jsonInfo) {
        ArrayList<Magazine> list = null;
        try {
            Gson gson = new Gson();
            Type type = new TypeToken<ArrayList<Magazine>>() {
            }.getType();

            list = gson.fromJson(jsonInfo, type);
        } catch (Exception e) {
            list = null;
        }
        return list;

    }

    public class MagazineAdapter extends BaseAdapter {

        private LayoutInflater inflater;

        ArrayList<Magazine> magazines;

        public MagazineAdapter(ArrayList<Magazine> magazines) {
            inflater = getLayoutInflater(getArguments());
            this.magazines = magazines;
        }

        public void changeMagazines(ArrayList<Magazine> magazines) {
            this.magazines = magazines;
            this.notifyDataSetChanged();
        }

        class ViewHolder {
            ImageView frontcover;

            ImageView titleImage;

            TextView title;

            Magazine magazine;
        }

        public int getCount() {
            return magazines.size();
        }

        public Object getItem(int position) {
            return magazines.get(position);
        }

        public long getItemId(int position) {
            return magazines.get(position).hashCode();
        }

        public View getView(int position, View convertView, ViewGroup parent) {

            if (convertView == null) {
                convertView = inflater.inflate(R.layout.magazine_item, null);
            }
            ViewHolder vh = (ViewHolder) convertView.getTag();

            if (vh == null) {
                vh = new ViewHolder();
                vh.frontcover = (ImageView) convertView.findViewById(R.id.frontcover);
                vh.title = (TextView) convertView.findViewById(R.id.titleText);
                vh.titleImage = (ImageView) convertView.findViewById(R.id.titleImage);
            }
            Magazine magazine = magazines.get(position);
            vh.magazine = magazine;
            vh.title.setText(magazine.name);
            if (magazine.exists) {
                String urls = Utils.MAGAZINE_DIR + "/" + magazine.filename + ";" + magazine.cover;
                mImageZipLoader.loadImage(urls, vh.frontcover);
                vh.titleImage.setImageResource(R.drawable.label_full);
            } else {
                mImageNetLoader.loadImage(HttpUtils.SITE_COVER + magazine.cover, vh.frontcover);
                vh.titleImage.setImageResource(R.drawable.label_light);
            }
            convertView.setTag(vh);
            return convertView;
        }

    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        final Magazine magazine = ((MagazineAdapter.ViewHolder) view.getTag()).magazine;
        if (magazine == null || TextUtils.isEmpty(magazine.filename)) {
            return;
        }
        if (Utils.checkFile(Utils.MAGAZINE_DIR + "/" + magazine.filename)) {
            Intent intent = new Intent(getActivity(), ModelDetailActivity.class);

            intent.putExtra("filename", magazine.filename);
            startActivity(intent);
        } else {

            int connectState = HttpUtils.getNetConnectState(getActivity());
            if (connectState == HttpUtils.STATE_CONNECT_NONE) {
                Toast.makeText(getActivity(), R.string.net_unconnect, Toast.LENGTH_SHORT).show();
                return;
            } else {
                String message = getString(R.string.prompt_download);
                if (connectState == HttpUtils.STATE_CONNECT_MOBILE) {
                    message = getString(R.string.prompt_net_mobile_download);
                }
                new AlertDialog.Builder(getActivity()).setTitle(R.string.prompt)
                        .setMessage(message)
                        .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.dismiss();

                            }
                        })
                        .setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                downloadMagazine(magazine);
                            }
                        }).show();
            }
        }
    }

    private static class ExecuteHandler extends Handler {
        private WeakReference<MagazineFragment> mFramgent;

        public ExecuteHandler(MagazineFragment fragment) {
            mFramgent = new WeakReference<MagazineFragment>(fragment);
        }

        @Override
        public void handleMessage(Message msg) {
            MagazineFragment f = mFramgent.get();
            if (f != null) {
                f.handleMessage(msg);
            }
        }

    }

    private void handleMessage(Message msg) {

        switch (msg.what) {
            case MSG_GET_POINT_RETURN:
                tvNowpoint.setText("" + mPoint);
                break;
            case MSG_GET_POINT:
                getPoint();
                break;
            case MSG_UPDATE_POINT_ERROR:
//                Toast.makeText(getActivity(), R.string.update_point_error, Toast.LENGTH_LONG)
//                        .show();
                break;
            case MSG_SPEND_POINT:
                final int cost = msg.arg1;
                final UpdatePointListener listener = (UpdatePointListener) msg.obj;
                showSpendDialog(cost, listener);

                break;
            case MSG_UPDATE_GRIDVIEW:
                UpdateTask updateTask = new UpdateTask(gridView);
                updateTask.execute(HttpUtils.DOMAIN + "magazine_info");
                break;
            case MSG_NOT_ENOUGH:
                showNotEnoughDialog();
                break;
        }

    }

    class DownloadMagazineListener implements UpdatePointListener {
        private Magazine mMagazine;

        public DownloadMagazineListener(Magazine magazine) {
            mMagazine = magazine;
        }

        @Override
        public void onSuccess(String arg0, int arg1) {
            Message msg = mHandler.obtainMessage(MSG_GET_POINT_RETURN);
            mPoint = arg1;
            mHandler.sendMessage(msg);

            download(HttpUtils.SITE_MAGAZINE + mMagazine.filename);
        }

        @Override
        public void onError(String arg0) {
            mHandler.sendEmptyMessage(MSG_UPDATE_POINT_ERROR);
        }
    };

    private void getPoint() {

        UUAppConnect.getInstance(getActivity()).getPoints(new UpdatePointListener() {

            @Override
            public void onSuccess(String arg0, int arg1) {
                Message msg = new Message();
                msg.what = MSG_GET_POINT_RETURN;
                mPoint = arg1;
                mHandler.sendMessage(msg);
            }

            @Override
            public void onError(String arg0) {
                mHandler.sendEmptyMessage(MSG_UPDATE_POINT_ERROR);
            }
        });

    }

    private void download(String url) {
        DownloadTask downloaderTask = new DownloadTask(getActivity(),
                new DownloadTask.DownloadFinishCallback() {

                    @Override
                    public void onFinish(String filepath) {
                        UpdateTask updateTask = new UpdateTask(gridView);
                        updateTask.execute(HttpUtils.DOMAIN + "magazine_info");
                    }
                });
        downloaderTask.execute(url);
    }

    /**
     * 下载杂志
     * 
     * @param magazineName
     */
    private void downloadMagazine(final Magazine magazine) {
        if (magazine.cost == 0) {

            download(HttpUtils.SITE_MAGAZINE + magazine.filename);
        } else {
            if (magazine.cost > mPoint) {
                showNotEnoughDialog();
            } else {
                showSpendDialog(magazine.cost, new DownloadMagazineListener(magazine));
            }
        }
    }

    /**
     * 积分不够 对话框
     */
    private void showNotEnoughDialog() {
        new AlertDialog.Builder(getActivity()).setTitle(R.string.prompt)
                .setMessage(R.string.prompt_point_not_enough)
                .setPositiveButton(R.string.get_point, new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        UUAppConnect.getInstance(getActivity()).showOffers();
                        dialog.dismiss();
                    }
                }).setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                }).show();
    }

    /**
     * 话费积分对话框
     * 
     * @param cost
     * @param listener
     */
    private void showSpendDialog(final int cost, final UpdatePointListener listener) {
        new AlertDialog.Builder(getActivity()).setTitle(R.string.download_file)
                .setMessage(getString(R.string.prompt_buy, cost))
                .setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        UUAppConnect.getInstance(getActivity()).spendPoints(cost, listener);
                    }
                }).setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                }).show();
    }

    public void downloadApk(final String apkSite) {
        DownloadTask downloaderTask = new DownloadTask(getActivity(),
                new DownloadTask.DownloadFinishCallback() {

                    @Override
                    public void onFinish(String filepath) {
                        Intent intent = new Intent();
                        intent.setAction(Intent.ACTION_VIEW);
                        intent.setDataAndType(Uri.parse("file://" + filepath),
                                "application/vnd.android.package-archive");
                        startActivity(intent);
                    }
                });
        downloaderTask.execute(apkSite);
    }

    public void showUpgradeDialog(String versionName, final String apkSite,
            String currentVersionName) {
        new AlertDialog.Builder(getActivity()).setTitle(R.string.upgrade_title)
                .setMessage(getString(R.string.upgrade_message, currentVersionName, versionName))
                .setNegativeButton(R.string.not_upgrade, new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                }).setPositiveButton(R.string.upgrade, new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        downloadApk(apkSite);

                    }
                }).show();
    }

    private class UpgradeInfo {
        String oldVersionName;

        String newVersionName;

        int oldVersionCode;

        int newVersionCode;

        String apkSite;

    }

    private class UpgradeTask extends AsyncTask<Void, Void, UpgradeInfo> {

        @Override
        protected UpgradeInfo doInBackground(Void... params) {
            String json = HttpUtils.loadString(HttpUtils.SITE_UPGRADE);
            if (json == null || TextUtils.isEmpty(json)) {
                return null;
            }

            try {
                JSONObject jsonObject = new JSONObject(json);

                PackageInfo info = getActivity().getPackageManager().getPackageInfo(
                        getActivity().getPackageName(), 0);
                UpgradeInfo upgradeInfo = new UpgradeInfo();
                upgradeInfo.oldVersionCode = info.versionCode;
                upgradeInfo.newVersionCode = jsonObject.optInt("versionCode");
                upgradeInfo.oldVersionName = info.versionName;
                upgradeInfo.newVersionName = jsonObject.optString("versionName");
                upgradeInfo.apkSite = jsonObject.optString("apk");
                return upgradeInfo;
            } catch (JSONException e) {
                e.printStackTrace();
            } catch (NameNotFoundException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(UpgradeInfo result) {

            if (result != null && result.oldVersionCode < result.newVersionCode) {
                showUpgradeDialog(result.newVersionName, result.apkSite, result.oldVersionName);
            }

        }

    }
}
